package com.algrithom.bitoper;

import com.google.common.base.Preconditions;

public class BitOper {
    
    public static void main(String[] args){
        System.out.println("Even data is: " + isEvenNumber(10));
        System.out.println("Odd data is: " + isOddNumber(10));
        System.out.println("10 ^ 5 is: " + power(10,5));
        System.out.println("19 % 16 is: " + mod(19,16));
        intMaxValue();
        intMinValue();
        System.out.println("to 16 : " + convert2Radx(26,16));
        System.out.println("to 16 : " + radix2Ten("010",2));
    }
    
    public static boolean isOddNumber(int n){
        return (n & 1) == 1;
    }
    
    public static boolean isEvenNumber(int n){
        return (n & 1) == 0;
    }
    
    public static int power(int n,int m){
        int temp = 1, base = n;
        while (m != 0) {
            if ((m & 1) == 1) {
                temp = temp * base;
            }
            base = base * base;
            m >>= 1;
        }
        return temp;
    }
    
    public static int mod(int m,int n){
        Preconditions.checkArgument(n >= 1);
        return m & (n - 1);
    }
    
    private static void intMaxValue(){
        int maxInt = (1 << 31) - 1;
        int maxInt1 = ~(1 << 31);
        int maxInt2 = (1 << -1) - 1;
        int maxInt3 = (-1 >>> 1);
        System.out.println("十进制: " + maxInt + " ,二进制: " + Integer.toBinaryString(maxInt));
        System.out.println("十进制: " + maxInt1 + " ,二进制: " + Integer.toBinaryString(maxInt1));
        System.out.println("十进制: " + maxInt2 + " ,二进制: " + Integer.toBinaryString(maxInt2));
        System.out.println("十进制: " + maxInt3 + " ,二进制: " + Integer.toBinaryString(maxInt3));
    }
    
    private static void intMinValue(){
        int minInt = 1 << 31;
        int minInt1 = -1 << 31;
        int minInt2 = 1 << -1;
        System.out.println("十进制: " + minInt + " ,二进制: " + Integer.toBinaryString(minInt));
        System.out.println("十进制: " + minInt1 + " ,二进制: " + Integer.toBinaryString(minInt1));
        System.out.println("十进制: " + minInt2 + " ,二进制: " + Integer.toBinaryString(minInt2));
        System.out.println("十进制: " + 0x80000000 + " ,二进制: " + Integer.toBinaryString(0x80000000));
    }
    
    /**
     * 10进制转换为任意进制
     */
    private static String convert2Radx(int value,int radix){
        StringBuilder stringBuilder = new StringBuilder();
        int tmp;
        while (value != 0) {
            tmp = value % radix;
            if (tmp > 9) {
                stringBuilder.append((char)(tmp - 10 + 'a'));
            } else {
                stringBuilder.append((char)(tmp + '0'));
            }
            value = value / radix;
        }
        return stringBuilder.reverse().toString();
    }
    
    /**
     * 16进制以下转变为10进制
     * 
     * @param str
     * @param radix
     * @return
     */
    private static int radix2Ten(String str,int radix){
        int tmp = 0;
        for (char ch : str.toCharArray()) {
            if (ch >= '0' && ch <= '9') {
                tmp = tmp * radix + ch - '0';
            } else {
                tmp = tmp * radix + ch - 'a' + 10;
            }
        }
        return tmp;
    }
}
